/****
 * Copyright (C) 2006 dNux Team
 *                                                            ****
 * This program is free software; you can redistribute it and/or *
 * modify under the terms of the GNU General Public License as   *
 * published by the Free Software Foundation;                    *
 * either version 2 of the License.                              *
 *                                                               *
 * This program is distributed in the hope that it will be       *
 * useful, but WITHOUT ANY WARRANTY; without even the implied    *
 * warranty of without even the implied waranty of               *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.          *
 * See the GNU General Public License for more details.          *
 *                                                               *
 * You should have received a copy of the                        *
 * GNU General Public License                                    *
 * along with this program; if not, write to the                 *
 * Free Software Foundation, Inc.,                               *
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. *
 *                                                               *
 ****                                                         ****/

void
process_new(d_check_t *check)
{
  d_process_t *process=NULL;
  process = d_process_new("ls");
  if ( ! process) {
    d_check_add(check, D_CHECK_ERROR, "process::new => is NULL !");
  } else {
    d_check_add(check, D_CHECK_OK, "process::new => great");
    d_process_free(&process);
  }
}

void
process_free(d_check_t *check)
{
  d_process_t *process = NULL;
  process = d_process_new("ls");
  d_process_free(&process);
  if ( process ) {
    d_check_add(check, D_CHECK_ERROR, "process::free => process is not NULL !");
  } else {
    d_check_add(check, D_CHECK_OK, "process::free => process is NULL.");
  }
}

void
process_run(d_check_t *check)
{
  int ret=0;
  d_process_t *process=NULL;
  process = d_process_new("ls");
  d_process_run(process);
  ret = d_process_wait(process);
  if (ret == EXIT_SUCCESS) {
    d_check_add(check, D_CHECK_OK, "process::run => ls return EXIT_SUCCESS.");
  } else {
    d_check_add(check, D_CHECK_ERROR, "process::run => ls return EXIT_FAILURE.");    
  }
  d_process_free(&process);
}

void
process_add_arg(d_check_t *check)
{
  int ret;
  d_process_t *process = d_process_new("touch");
  d_process_add_arg(process, "/dev/null");
  d_process_run(process);
  ret = d_process_wait(process);
  if (ret == EXIT_SUCCESS) {
    d_check_add(check, D_CHECK_OK, "process::add_arg => touch /dev/null return EXIT_SUCCESS");
  } else {
    d_check_add(check, D_CHECK_ERROR, "process::add_arg => touch /dev/null return EXIT_FAILURE");
  }
  d_process_free(&process);
}

void
process_send_signal(d_check_t *check)
{
  time_t t;
  int t2;

  d_process_t *process = d_process_new("sleep");
  d_process_add_arg(process, "15");
  t = time(NULL);
  d_process_run(process);
  d_process_send_signal(process, SIGKILL);
  t2 = time(NULL) - t;
  if (t2 < 2) {
    d_check_add(check, D_CHECK_OK, "process::send_signal => process run < 2 sec");
  } else {
    d_check_add(check, D_CHECK_ERROR, "process::send_signal => process run >= 2 sec");
  }
  d_process_free(&process);
}

void
process_get_stdout(d_check_t *check)
{
  int fd, len;
  char buff[2048];
  
  d_process_t *process = d_process_new("echo");
  d_process_add_arg(process, "hello");
  d_process_run(process);
  fd = d_process_get_stdout(process);
  d_process_wait(process);
  if ((len = read(fd, buff, sizeof(buff))) < 1) {
    d_check_add(check, D_CHECK_ERROR, "process::get_stdout => buff < 1.");
    goto error;
  }
  buff[len-1] = '\0';

  if (strcmp(buff, "hello")) {
    d_check_add(check, D_CHECK_ERROR, "process::get_stdout => buff not equal hello.");
    goto error;
  }
  d_check_add(check, D_CHECK_OK, "process::get_stdout => buff equal hello");
 error:
  d_process_free(&process);
  return;
}

void
process_get_stderr(d_check_t *check)
{
  int fd, len;
  char buff[2048];
  
  d_process_t *process = d_process_new("gcc");
  d_process_run(process);
  fd = d_process_get_stderr(process);
  d_process_wait(process);
  if ((len = read(fd, buff, sizeof(buff))) < 1) {
    d_check_add(check, D_CHECK_ERROR, "process::get_stderr => buff < 1.");
    goto error;
  }
  buff[len-1] = '\0';

  if (strcmp(buff, "gcc: no input files")) {
    d_check_add(check, D_CHECK_ERROR, "process::get_stderr => buff not equal 'gcc: no input file'.");
    goto error;
  }
  d_check_add(check, D_CHECK_OK, "process::get_stderr => buff equal 'gcc: no input file'.");
 error:
  d_process_free(&process);
  return;
}

void
process_get_stdin(d_check_t *check)
{
  int in, out, len;
  char buff[2048];
  
  d_process_t *process = d_process_new("cat");
  d_process_add_arg(process, "/dev/stdin");

  d_process_run(process);
  in  = d_process_get_stdin(process);
  out = d_process_get_stdout(process);
  
  write(in, "hello\n", strlen("hello\n"));
  if ((len = read(out, buff, sizeof(buff))) < 1) {
    d_check_add(check, D_CHECK_ERROR, "process::get_stdin => buff < 1.");
    goto error;
  }
  buff[len-1] = '\0';
  if (strcmp(buff, "hello")) {
    d_check_add(check, D_CHECK_ERROR, "process::get_stdin => buff not equal 'hello'.");
    goto error;
  }
  d_check_add(check, D_CHECK_OK, "process::get_stdin => buff equal 'hello'.");
 error:
  d_process_send_signal(process, SIGINT);
  d_process_wait(process);
  d_process_free(&process);
  return;
}

void
process_last_run(d_check_t *check)
{
  d_process_t *process = d_process_new("ls");
  time_t t = time(NULL);
  d_process_run(process);
  d_process_wait(process);
  if (t != d_process_get_last_run(process)) {
    d_check_add(check, D_CHECK_ERROR, "process::last_run => unix time different");
    goto error;
  }
  sleep(1);
  d_process_run(process);
  d_process_wait(process);
  if (t == d_process_get_last_run(process)) {
    d_check_add(check, D_CHECK_ERROR, "process::last_run => unix time identique.");
    goto error;
  }
  d_check_add(check, D_CHECK_OK, "process::last_run => every think look nice.");
 error:
  d_process_free(&process);
  return;
}


void
process_tests(d_check_t *check)
{
  fprintf(stdout, ">> process_tests <<\n");
  process_new(check);
  process_free(check);
  process_run(check);
  process_add_arg(check);
  process_send_signal(check);
  process_get_stdout(check);
  process_get_stderr(check);
  process_get_stdin(check);
  process_last_run(check);

  fprintf(stdout, "\n");
}
